package com.link.base.wechat.wxcard.service;


import com.alibaba.fastjson.JSONObject;
import com.link.base.base.member.model.GiftCardWx;
import com.link.base.wechat.wxcard.model.*;
import com.link.base.wechat.wxcard.util.WxCardUtil;
import com.link.base.wechat.wxlog.model.WxLogModule;
import com.link.base.wechat.wxlog.service.WxLogService;
import com.link.base.wechat.wxtoken.model.WxToken;
import com.link.base.wechat.wxtoken.service.WxTokenService;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信公众号卡券实现类
 *
 * @author lujiang
 * @date 2019/02/26 18:45
 */
@Service
public class WxCardInfoServiceImpl implements WxCardInfoService {

    @Resource
    private WxTokenService wxTokenService;

    @Resource
    private WxLogService wxLogService;

    @Override
    public Map<String, Object> upsertWxCard(String wxAppId, WxCardInfo wxCardInfo, String rowStatus) throws Exception {
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        String token = wxToken.getAccess_token();
        // 数据检验
        checkCreateWxCardInfo(token, wxCardInfo, rowStatus);
        // 校验不支持修改字段
        if (StringUtils.equals(rowStatus, "UPDATE")) {
            if (null != wxCardInfo.getBaseInfo().getNeedPushOnView()) {
                throw new ServiceException("WXCARD-001");
            }
            if (null != wxCardInfo.getBaseInfo().getSku()) {
                throw new ServiceException("WXCARD-002");
            }
            if (null != wxCardInfo.getBaseInfo().getNeedPushOnView()) {
                throw new ServiceException("WXCARD-003");
            }
            if (null != wxCardInfo.getBaseInfo().getUseCustomCode()) {
                throw new ServiceException("WXCARD-004");
            }
            if (StringUtils.isNotBlank(wxCardInfo.getBaseInfo().getBrandName())) {
                throw new ServiceException("WXCARD-005");
            }
        }
        // 按照格式生成json字符串
        String cardJson = getCardJson(wxCardInfo, rowStatus);
        // 发起请求
        Map<String, Object> result = WxCardUtil.createWxCard(token, rowStatus, cardJson);
        wxLogService.log(WxLogModule.wxLogCard, "微信卡券",
            "新增/修改微信卡券，卡券名称 => " + wxCardInfo.getBaseInfo().getTitle(), wxAppId, wxToken.getCorpid());
        return result;
    }


    @Override
    public int updateMember(String wxAppId, WxUpdateMemberInfo info) throws Exception {
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        // 必填字段
        if (null == wxToken.getAccess_token()) {
            throw new ServiceException("WXCARD-006");
        }
        if (StringUtils.isBlank(info.getCode())) {
            throw new ServiceException("WXCARD-007");
        }
        if (StringUtils.isBlank(info.getCardId())) {
            throw new ServiceException("WXCARD-008");
        }
        // 数据处理
        Map<String, Object> map = new HashMap<>(16);
        map.put("card_id", info.getCardId());
        map.put("code", info.getCode());
        map.put("background_pic_url", info.getBackgroundPicUrl());
        map.put("custom_field_value1", info.getCustomFieldValue1());
        map.put("custom_field_value2", info.getCustomFieldValue2());
        map.put("custom_field_value3", info.getCustomFieldValue3());
        map.put("record_bonus", info.getRecordBonus());
        map.put("record_balance", info.getRecordBalance());
        map.put("notify_optional", info.getNotifyOptional());
        if (0 != info.getAddBalance()) {
            map.put("add_balance", info.getAddBalance());
        }
        if (0 != info.getAddBonus()) {
            map.put("add_bonus", info.getAddBonus());
        }
        if (0 != info.getBalance()) {
            map.put("balance", info.getBalance());
        }
        if (0 != info.getBonus()) {
            map.put("bonus", info.getBonus());
        }
        // 驼峰转下划线
        String memberJson = WxCardUtil.getJsonData(map);
        int num = WxCardUtil.updateMemberInfo(wxToken.getAccess_token(), memberJson);
        wxLogService.log(WxLogModule.wxLogCard, "修改会员信息",
            "修改会员信息，code => " + info.getCode() + "；card_id => " + info.getCardId(),
                wxAppId, wxToken.getCorpid());
        return num;
    }

    @Override
    public int activeCard(String wxAppId, CardActive cardActive) throws Exception {
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        String token = wxToken.getAccess_token();
        // 校验必填
        if (null == token) {
            throw new ServiceException("WXCARD-006");
        }
        if (StringUtils.isBlank(cardActive.getCardId())) {
            throw new ServiceException("WXCARD-008");
        }
        if (null == cardActive.getRequiredForm()) {
            throw new ServiceException("WXCARD-009");
        }
        // 驼峰转下换线
        String activeCardJson = WxCardUtil.getJsonData(cardActive);
        int num = WxCardUtil.activeCard(token, activeCardJson);
        wxLogService.log(WxLogModule.wxLogCard, "激活卡券",
            "激活会员卡信息，卡券Id => " + cardActive.getCardId(), wxAppId, wxToken.getCorpid());
        return num;
    }

    @Override
    public Map<String, Object> upsertGiftCardPage(String wxAppId, Page page, String rowStatus) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        result = WxCardUtil.upsertGiftCardPage(wxToken.getAccess_token(), page, rowStatus);
        wxLogService.log(WxLogModule.wxLogCard, "卡券货架",
            "创建/修改卡券货架信息，货架Id => " + page.getPageId(), wxAppId, wxToken.getCorpid());
        return result;
    }

    @Override
    public Map<String, Object> setGiftCardWxa(GiftCardWx giftCardWx, String wxAppId) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        result = WxCardUtil.setGiftCardWxa(giftCardWx, wxToken.getAccess_token());
        wxLogService.log(WxLogModule.wxLogCard, "卡券货架",
            "货架绑定小程序，货架Id => " + giftCardWx.getPageId() + "，小程序Id => " + giftCardWx.getWxaAppid(),
                wxAppId, wxToken.getCorpid());
        return result;
    }

    /**
     * 创建卡券数据必输校验
     *
     * @author lujiang
     * @date 2019/02/26 20:00
     * @param token      access_token
     * @param wxCardInfo 卡券信息
     * @param status     NEW OR UPDATE
     * @throws Exception
     */
    private void checkCreateWxCardInfo(String token, WxCardInfo wxCardInfo, String status) throws Exception {
        if (null == token) {
            throw new ServiceException("WXCARD-006");
        }
        if (null == wxCardInfo.getSupplyBonus()) {
            throw new ServiceException("WXCARD-010");
        } else if (wxCardInfo.getSupplyBonus()) {
            //若显示积分，积分相关字段必填
            BonusRule bonusRule = wxCardInfo.getBonusRule();
            if (null == bonusRule.getCostBonusUnit()
                || null == bonusRule.getCostMoneyUnit()
                || null == bonusRule.getIncreaseBonus()
                || null == bonusRule.getInitIncreaseBonus()
                || null == bonusRule.getLeastMoneyToUseBonus()
                || null == bonusRule.getMaxIncreaseBonus()
                || null == bonusRule.getMaxReduceBonus()
                || null == bonusRule.getReduceMoney()) {
                throw new ServiceException("WXCARD-011");
            }
        }
        // 会员卡
        if (StringUtils.equals(wxCardInfo.getCardType(), "MEMBER_CARD")) {
            if (StringUtils.isBlank(wxCardInfo.getPrerogative())) {
                throw new ServiceException("WXCARD-012");
            }
            if (null == wxCardInfo.getSupplyBalance()) {
                throw new ServiceException("WXCARD-013");
            } else if (wxCardInfo.getSupplyBalance() == true) {
                if (StringUtils.isBlank(wxCardInfo.getBalanceRules())) {
                    throw new ServiceException("WXCARD-014");
                }
            }
            // 校验基础信息
            checkBaseInfo(wxCardInfo.getBaseInfo(), status);
        } else if (StringUtils.equals(wxCardInfo.getCardType(), "GROUPON")) {
            // 优惠券
            // 校验基础信息
            checkBaseInfo(wxCardInfo.getBaseInfo(), status);
            if (null == wxCardInfo.getBaseInfo().getDateInfo().getBeginTimestamp()
                || null == wxCardInfo.getBaseInfo().getDateInfo().getEndTimestamp()
                || StringUtils.isBlank(wxCardInfo.getBaseInfo().getDateInfo().getFixedBeginTerm() + "")
                || StringUtils.isBlank(wxCardInfo.getBaseInfo().getDateInfo().getFixedTerm() + "")
                || StringUtils.isBlank(wxCardInfo.getBaseInfo().getDateInfo().getType())) {
                throw new ServiceException("WXCARD-015");
            }
        } else if (StringUtils.equals(wxCardInfo.getCardType(), "GENERAL_CARD")) {
            if (StringUtils.isBlank(wxCardInfo.getSubCardType())) {
                throw new ServiceException("WXCARD-016");
            }
            if (null != wxCardInfo.getBaseInfo() && null == wxCardInfo.getBaseInfo().getGiftcardInfo()) {
                throw new ServiceException("WXCARD-017");
            }
        }
    }

    /**
     * 创建卡券时校验卡券基础信息(必输校验)
     *
     * @author lujiang
     * @date 2019/02/26 20:00
     * @param baseInfo 卡券信息
     * @param status   创建 or 修改
     * @throws Exception
     */
    private void checkBaseInfo(BaseInfo baseInfo, String status) throws Exception {
        if (StringUtils.isBlank(baseInfo.getLogoUrl())) {
            throw new ServiceException("WXCARD-018");
        }
        if (StringUtils.isBlank(baseInfo.getCodeType())) {
            throw new ServiceException("WXCARD-019");
        }
        if (StringUtils.equals(status, "NEW")
            && StringUtils.isBlank(baseInfo.getBrandName())) {
            throw new ServiceException("WXCARD-020");
        }
        if (StringUtils.isBlank(baseInfo.getTitle())) {
            throw new ServiceException("WXCARD-021");
        }
        if (StringUtils.isBlank(baseInfo.getColor())) {
            throw new ServiceException("WXCARD-022");
        }
        if (StringUtils.isBlank(baseInfo.getNotice())) {
            throw new ServiceException("WXCARD-023");
        }
        if (StringUtils.isBlank(baseInfo.getDescription())) {
            throw new ServiceException("WXCARD-024");
        }
        if (StringUtils.equals(status, "NEW")
            && StringUtils.isBlank(baseInfo.getSku().getQuantity() + "")) {
            throw new ServiceException("WXCARD-025");
        }
        if (StringUtils.isBlank(baseInfo.getDateInfo().getType())) {
            throw new ServiceException("WXCARD-026");
        }
    }

    /**
     * 获取创建卡券json字符串
     *
     * @author lujiang
     * @date 2019/02/26 21:10
     * @param wxCardInfo 卡券对象
     */
    private String getCardJson(WxCardInfo wxCardInfo, String rowStatus) throws Exception {
        Map<String, Object> memberCardMap = new HashMap<>(16);
        // 会员类目
        if (null != wxCardInfo.getCustomFieldList()) {
            for (int i = 0; i < wxCardInfo.getCustomFieldList().size(); i++) {
                int num = i + 1;
                String key = "custom_field" + num;
                memberCardMap.put(key, wxCardInfo.getCustomFieldList().get(i));
            }
        }
        //自定义入口
        if (null != wxCardInfo.getCustomCellList()) {
            int size = 2;
            if (wxCardInfo.getCustomCellList().size() <= size) {
                size = wxCardInfo.getCustomCellList().size();
            } else {
                CustomCell cell = wxCardInfo.getCustomCellList().get(2);
                wxCardInfo.getBaseInfo().setPromotionUrl(cell.getUrl());
                wxCardInfo.getBaseInfo().setPromotionUrlName(cell.getName());
                wxCardInfo.getBaseInfo().setPromotionAppBrandPass(cell.getAppBrandPass());
                wxCardInfo.getBaseInfo().setPromotionAppBrandUserName(cell.getAppBrandUserName());
                wxCardInfo.getBaseInfo().setPromotionUrlSubTitle(cell.getTips());
            }
            for (int i = 0; i < size; i++) {
                wxCardInfo.getCustomCellList().get(i).setUrlType(null);
                int num = i + 1;
                String key = "custom_cell" + num;
                memberCardMap.put(key, wxCardInfo.getCustomCellList().get(i));
            }
        }
        memberCardMap.put("background_pic_url", wxCardInfo.getBackGroundUrl());
        memberCardMap.put("prerogative", wxCardInfo.getPrerogative());
        memberCardMap.put("wx_activate", wxCardInfo.getWxActivate());
        memberCardMap.put("supply_bonus", wxCardInfo.getSupplyBonus());
        memberCardMap.put("bonus_rule", wxCardInfo.getBonusRule());
        memberCardMap.put("supply_balance", wxCardInfo.getSupplyBalance());
        memberCardMap.put("balance_rules", wxCardInfo.getBalanceRules());
        memberCardMap.put("base_info", wxCardInfo.getBaseInfo());
        memberCardMap.put("advanced_info", wxCardInfo.getAdvancedInfo());
        memberCardMap.put("auto_activate", wxCardInfo.getAutoActivate());
        memberCardMap.put("activate_url", wxCardInfo.getActivateUrl());
        memberCardMap.put("sub_card_type", wxCardInfo.getSubCardType());
        String member = "MEMBER_CARD";
        // 默认为会员卡
        String type = "member_card";
        if (null == wxCardInfo.getCardType()) {
            wxCardInfo.setCardType(member);
        }
        // 卡券类型
        String cardType = wxCardInfo.getCardType();
        // 不同卡券的特有属性
        switch (cardType) {
            case "GROUPON":
                memberCardMap.put("deal_detail", wxCardInfo.getDealDetail());
                type = "groupon";
                break;
            //现金
            case "CASH":
                memberCardMap.put("least_cost", wxCardInfo.getLeastCost());
                memberCardMap.put("reduce_cost", wxCardInfo.getReduceCost());
                type = "cash";
                break;
            //折扣
            case "DISCOUNT":
                memberCardMap.put("discount", wxCardInfo.getDiscount());
                type = "discount";
                break;
            //礼物
            case "GIFT":
                memberCardMap.put("gift", wxCardInfo.getGift());
                type = "gift";
                break;
            case "GENERAL_COUPON":
                memberCardMap.put("default_detail", wxCardInfo.getDefaultDetail());
                type = "general_coupon";
                break;
            // 会员卡
            case "MEMBER_CARD":
                type = "member_card";
                break;
            // 礼品卡
            case "GENERAL_CARD":
                memberCardMap.put("init_balance", wxCardInfo.getInitBalance());
                type = "general_card";
                break;
            default:
                break;
        }
        String data = null;
        Map<String, Object> cardMap = new HashMap<>(16);
        cardMap.put(type, memberCardMap);
        // 修改卡券
        if (StringUtils.equals(rowStatus, "UPDATE")) {
            cardMap.put("card_id", wxCardInfo.getCardId());
            data = WxCardUtil.getJsonData(cardMap);
        } else if (StringUtils.equals(rowStatus, "NEW")) {
            // 创建卡券
            cardMap.put("card_type", wxCardInfo.getCardType());
            Map<String, Object> card = new HashMap<>(16);
            card.put("card", cardMap);
            data = WxCardUtil.getJsonData(card);
        }
        return data;
    }

    @Override
    public String codeDecrypt(String wxAppId, String encryptCode) throws Exception {
        if (StringUtils.isBlank(wxAppId)) {
            throw new ServiceException("WXCARD-027");
        }
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        JSONObject result = WxCardUtil.codeDecrypt(wxToken.getAccess_token(), encryptCode);
        return result.getString("code");
    }

    @Override
    public Map<String, String> getExtraData(String wxAppId, String cardId, String outerStr) throws Exception {
        if (StringUtils.isBlank(wxAppId)) {
            throw new Exception("wxAppId不能为空！");
        }
        WxToken wxToken = wxTokenService.getWxAccessTokenByAppId(wxAppId);
        String token = wxToken.getAccess_token();
        return WxCardUtil.getExtraData(cardId, outerStr, token);
    }

}
